<template>
	<view>

		<!-- 连接蓝牙动画 -->
		<u-popup :show="bluePop" :round="35">
			<view class="popViewBlue">
				<view class="title">蓝牙开机</view>

				<!-- 开机中、开机成功 -->
				<view v-if="blueOpen">
					<view v-if="blueSuccess">
						<view class="successImg">
							<u--image src="http://image.baestandard.com/1710913438683success.png" width="162rpx"
								height="auto" mode="widthFix"></u--image>
						</view>
						<view class="msgText">开机成功</view>
						<view class="text">设备序列号：{{equipmentCoding || '暂无序列号'}}</view>
					</view>

					<view v-else>
						<view class="bindImg">
							<u--image src="http://image.baestandard.com/1710560423410.gif" width="100%" height="auto"
								mode="widthFix"></u--image>
						</view>
						<view class="msgText">设备正在开机中…</view>
						<view class="text">请确保在设备附近，且设备处于关机状态</view>
					</view>
				</view>

				<!-- 开机失败 -->
				<view v-else>
					<view class="slotTitle">开机失败</view>
					<view class="slotList">
						<view class="num">1</view>检查设备是否处于关机状态？
					</view>

					<view class="slotList">
						<view class="num">2</view>设备距离手机5米以内
					</view>

					<view class="slotList">
						<view class="num">3</view>检查设备或者手机蓝牙功能是否开启？
					</view>

					<view class="slotList">
						<view class="num">4</view>以上状态都未出现，请联系供应商帮助
					</view>
				</view>

				<view class="buts">
					<view class="">
						<u-button text="关闭" shape="circle" color="#EDEDED" @click="bluePop = false"
							:customStyle="{padding:'0 40rpx',height:'100rpx',color:'#151515',borderRadius:'36rpx'}">
						</u-button>
					</view>

					<view style="margin-left: 24rpx;" v-if="!blueOpen">
						<u-button text="重新开机" color="#007960" shape="circle" @click="initBlue()"
							:customStyle="{padding:'0 40rpx',height:'100rpx',borderRadius:'36rpx'}">
						</u-button>
					</view>
				</view>
			</view>
		</u-popup>
		<u-toast ref="uToast"></u-toast>
	</view>
</template>

<script>
	// UI基于uview2开发
	// message  监听消息传递
	// blueSend  指令成功监听  成功 success   失败  error
	
	export default {
		props: {
			deviceId: {type: String,required:true}, //蓝牙地址 必填
			equipmentCoding: {type: String,default:'暂无设备序列号'}, //设备序列号
			hexString:{type: String}, //消息命令
			msgTrue:{type:Boolean,default:false} //是否监听消息
		},
		data() {
			return {
				bluePop: false, //蓝牙连接弹出
				blueOpen: true, //是否正常打开
				serviceId: [], //所有蓝牙服务ID
				deviceIdReal:'', //蓝牙ID(传过来后编码)
				
				blueSuccess: false, //设备打开成功后打开
				deleteDeviceOpen: false, //设备解绑、培训完成弹出
				deleteDeviceLoading: false,
				devicetype: 1, //设备弹出类型 1解绑 2培训完成
				scrollTop: 0
			}
		},
		methods: {
			initBlue() { //打开蓝牙设备
				this.deviceIdReal = this.deviceId;
				let _this = this;
				this.bluePop = true; //弹出蓝牙
				this.blueOpen = true; // 蓝牙动画、开机成功
				this.blueSuccess = false; //蓝牙打开成功
				uni.openBluetoothAdapter({
					success(res) {
						if(uni.$u.os() == 'ios'){
							let deviceId = _this.deviceId.split(':').join('')
							uni.startBluetoothDevicesDiscovery({
							    success(res) {
									uni.onBluetoothDeviceFound(function (devices) {
										if(devices.devices[0].name && devices.devices[0].name.includes(deviceId)){
											_this.deviceIdReal = devices.devices[0].deviceId;
											uni.closeBLEConnection({
												deviceId: this.deviceIdReal,
												success() {
													_this.connectBlue() //连接蓝牙
													uni.stopBluetoothDevicesDiscovery() //停止搜索
												}
											});
										}
									})
							    }
							})
						}else{
							_this.connectBlue() //连接蓝牙
						}
					},
					fail(err) {
						_this.$refs.uToast.show({
							message: '请打开蓝牙',
							type: 'error',
							position: 'top'
						})
						_this.blueOpen = false;
					}
				})
			},
			connectBlue() { //检测是否连接蓝牙
				let _this = this;
				let deviceId = this.deviceIdReal;
				uni.getConnectedBluetoothDevices({
					success(res) {
						let bindTrue = true
						res.devices.forEach(item => {
							if (item.deviceId == deviceId) {
								bindTrue = false
								_this.getServices() //获取蓝牙服务
							}
						})
						if (bindTrue) {
							_this.bindBlue()
						}
					},
					fail() {
						_this.bindBlue()
					}
				})
			},
			bindBlue() { //连接蓝牙
				let _this = this;
				let deviceId = this.deviceIdReal;
				uni.createBLEConnection({
					deviceId: deviceId, //蓝牙设备ID
					success(res) {
						_this.getServices() //获取蓝牙服务
					},
					fail(err) {
						_this.$refs.uToast.show({
							message: '连接失败，请重试',
							type: 'error',
							position: 'top'
						})
						uni.closeBLEConnection({
							deviceId: deviceId
						});
						_this.blueOpen = false;
					}
				})
			},
			getServices() { //获取蓝牙服务
				let _this = this;
				setTimeout(() => {
					uni.getBLEDeviceServices({
						deviceId: this.deviceIdReal, //蓝牙设备ID
						success(res) {
							_this.$set(_this, 'serviceId', res.services) //所有蓝牙服务 []
							_this.send() // 向蓝牙设备发送信息
							if(_this.msgTrue){
								_this.notify()
							}
						},
						fail(err) {
							_this.$refs.uToast.show({
								message: '获取蓝牙服务失败',
								type: 'error',
								position: 'top'
							})
							_this.blueOpen = false;
						}
					})
				})
			},
			send() { // 向蓝牙设备发送一个0x00的16进制数据
				let _this = this;
				const arrayBuffer = new Uint8Array(_this.hexString.match(/[\da-f]{2}/gi).map(function(h) {
					return parseInt(h, 16)
				})).buffer;
				let deviceId = this.deviceIdReal; //蓝牙设备ID
				let serviceId = this.serviceId[1].uuid; //蓝牙服务ID

				uni.getBLEDeviceCharacteristics({
					deviceId: deviceId,
					serviceId: serviceId,
					success(sticId) {
						setTimeout(() => {
							uni.writeBLECharacteristicValue({
								deviceId: deviceId,
								serviceId: serviceId,
								characteristicId: sticId.characteristics[5].uuid, //特征uuid
								value: arrayBuffer,
								success(res) {
									_this.$refs.uToast.show({message: '蓝牙发送成功',type: 'success',position: 'top'})
									_this.blueSuccess = true;
									_this.$emit('blueSend', 'success')
								},
								fail(err) {
									_this.$emit('blueSend', 'error')
									_this.$refs.uToast.show({
										message: '蓝牙连接失败，请重新连接',
										type: 'error',
										position: 'top'
									})
								}
							})
						},1000)
					},
					fail(err) {
						_this.$refs.uToast.show({
							message: '蓝牙连接失败，请重新连接',
							type: 'error',
							position: 'top'
						})
						console.error(err)
					}
				})
			},
			notify() { //开启消息监听
				let _this = this;
				let deviceId = this.deviceIdReal; //蓝牙设备ID
				let serviceId = this.serviceId[1].uuid; //蓝牙服务ID
				
				// 获取蓝牙特征
				uni.getBLEDeviceCharacteristics({
					deviceId: deviceId,
					serviceId: serviceId,
					success(sticId) {
						
						// 订阅消息
						uni.notifyBLECharacteristicValueChange({
							deviceId: deviceId,
							serviceId: serviceId,
							characteristicId: sticId.characteristics[5].uuid, // 特征值
							state: true,
							success(res) {
								// 接受消息的方法
								_this.listenValueChange()
							},
							fail(err) {
								_this.$refs.uToast.show({message: '开启消息监听失败',type: 'error',position: 'top'})
							}
						})
					},
					fail(err) {
						_this.$refs.uToast.show({
							message: '获取特征值失败',
							type: 'error',
							position: 'top'
						})
						console.error(err)
					}
				})
			},
			listenValueChange() { //监听消息变化
				let _this = this;
				uni.onBLECharacteristicValueChange(res => {
					let resHex = _this.ab2hex(res.value)
					let result = _this.hexCharCodeToStr(resHex)
					_this.$emit('message',result)
				})
			},
			ab2hex(buffer) { //ArrayBuffer转16进度字符串示例
				const hexArr = Array.prototype.map.call(
					new Uint8Array(buffer),
					function(bit) {
						return ('00' + bit.toString(16)).slice(-2)
					}
				)
				return hexArr.join('')
			},
			hexCharCodeToStr(hexCharCodeStr) {
				var trimedStr = hexCharCodeStr.trim();
				var rawStr = trimedStr.substr(0, 2).toLowerCase() === "0x" ? trimedStr.substr(2) : trimedStr;
				var len = rawStr.length;
				if (len % 2 !== 0) {
					console.log("存在非法字符!");
					return "";
				}
				var curCharCode;
				var resultStr = [];
				for (var i = 0; i < len; i = i + 2) {
					curCharCode = parseInt(rawStr.substr(i, 2), 16);
					resultStr.push(String.fromCharCode(curCharCode));
				}
				return resultStr.join("");
			}
		}
	}
</script>

<style lang="scss" scoped>
	.popViewBlue {
		width: 100%;
		height: auto;
		background: #fff;
		padding: 48rpx 32rpx 224rpx;
		box-sizing: border-box;
		position: relative;
		border-radius: 64rpx;

		.title {
			width: 100%;
			height: 48rpx;
			font-weight: 600;
			font-size: 34rpx;
			color: #151515;
			line-height: 48rpx;
		}

		.bindImg {
			width: calc(100% - 200rpx);
			margin: 0 auto;
		}

		.successImg {
			width: 162rpx;
			height: 162rpx;
			margin: 144rpx auto 0;
		}

		.msgText {
			width: 100%;
			height: 52rpx;
			font-weight: 600;
			font-size: 38rpx;
			color: #151515;
			line-height: 52rpx;
			text-align: center;
			margin: 24rpx auto;
		}

		.text {
			width: 100%;
			font-weight: 400;
			font-size: 30rpx;
			color: #151515;
			text-align: center;
			line-height: 1.5;
		}

		.buts {
			width: 100%;
			position: absolute;
			bottom: 48rpx;
			right: 32rpx;
			display: flex;
			justify-content: flex-end;
		}

		.slotTitle {
			width: 100%;
			height: 58rpx;
			font-weight: 600;
			font-size: 42rpx;
			color: #151515;
			line-height: 58rpx;
			margin: 48rpx auto;
		}

		.slotList {
			display: flex;
			align-items: center;
			width: 100%;
			height: 52rpx;
			margin-bottom: 48rpx;

			.num {
				width: 36rpx;
				height: 36rpx;
				border-radius: 36rpx;
				background: #151515;
				font-weight: 600;
				font-size: 24rpx;
				color: #FFFFFF;
				line-height: 36rpx;
				text-align: center;
				margin-right: 26rpx;
			}
		}
	}
</style>